home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / Sample Code / Typography Samples / Basic Layout Sample ƒ / QDGX shell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-10  |  12.5 KB  |  433 lines  |  [TEXT/KAHL]

  1. /**\
  2. |**| =====================================================================
  3. |**|
  4. |**|    QDGX shell.c
  5. |**|
  6. |**|    This file is a shell that can be used to build "new" Graphics 
  7. |**|    applications.  It contains all of the required calls to use the "new"
  8. |**|    Graphics routines and QuickDraw (i.e. windows) together. It can put up
  9. |**|    one or more window.  This shell also supports GX printing.
  10. |**|
  11. |**|    The application is expected to supply the following functions which
  12. |**|    are called by this shell:
  13. |**|        void  DoSetup (void);
  14. |**|        void  DoDraw (WindowPtr);
  15. |**|        OSErr DoCreateNew (void);
  16. |**|        void  DoDispose (WindowPtr);
  17. |**|        void  DoIdle (WindowPtr);
  18. |**|        void  DoTeardown (void);
  19. |**|        void  DoClick (WindowPtr, Point);
  20. |**|
  21. |**|
  22. |**|    Change History:
  23. |**|        3/90    New
  24. |**|        6/91    PLA  Updated the shell to reflect the changes in
  25. |**|                     "Graphics" v1.0d21.2.
  26. |**|        6/92         Made the following variables global: gDebugging,
  27. |**|                     gGiveMeValidation,gGraphicsHeapSize.
  28. |**|                     See the comments for detail in this file.
  29. |**|        6/92    DMH  Added printing guts, mangled and reorganized.
  30. |**|        9/93    PLA  Updated files to work with the ß2 "GXified"
  31. |**|                     interface files.
  32. |**|        9/93    DMH  Added override for gxPrintingEvent to handle
  33. |**|                     update events.
  34. |**|        9/93    DMH  Added GXUpdateJob for resume events.
  35. |**|        12/93    MD   Extensive changes made for clarity, shell-like
  36. |**|                     ability, cleanliness.
  37. |**|        8/94    DH   More changes made for universal header and clarity
  38. |**|
  39. |**|    ©1992-1994  Apple Computer, Inc.
  40. |**|    All rights reserved.
  41. |**|
  42. |**| =====================================================================
  43. \**/
  44.  
  45.  
  46. #include "QDGX shell.h"
  47.  
  48.  
  49. /**\
  50. |**| ---------------------------------------------------------------------
  51. |**| GLOBALS
  52. |**| ---------------------------------------------------------------------
  53. \**/
  54. Boolean            gQuitting = false;
  55. long            gSleep = 0;
  56.  
  57. #if defined(powerc) && !defined(__MWERKS__)
  58. QDGlobals        qd;
  59. #endif
  60.  
  61.  
  62.  
  63.  
  64. /**\
  65. |**| ---------------------------------------------------------------------
  66. |**| main()
  67. |**| ---------------------------------------------------------------------
  68. \**/
  69. void main()
  70. {        
  71.     CursHandle            theCurs; 
  72.     Handle                menuBar;
  73.     OSErr                err;
  74.     WindowPtr            wind;
  75.     gxGraphicsClient     client;
  76.     
  77.     InitToolbox();
  78.  
  79.     theCurs = GetCursor(watchCursor);
  80.     SetCursor(*theCurs);
  81.  
  82.     menuBar = GetNewMBar(rMenuBar); // Create the menu bar.
  83.     SetMenuBar(menuBar);
  84.     DisposeHandle(menuBar);
  85.  
  86.     CheckQuickDrawGX();
  87.     if (gQuitting)
  88.     {
  89.         SetCursor(&qd.arrow);
  90.         (void) StopAlert(rNoQuickDrawGXID, NULL);
  91.         return;
  92.     }
  93.     
  94.     
  95.     // Before starting to draw, we'll call the DoSetup routine so we can initialize any
  96.     // global variables or behaviors.  This routine would be a good time to change the
  97.     // gGraphicsHeapSize variable before we make the new graphics client next.
  98.  
  99.     DoSetup();
  100.     
  101.     
  102.     // The GXNewGraphicsClient routine defines the graphics heap size.  If you do not make this
  103.     // call, the GX graphics engine will create this heap automatically.  How?  It will create
  104.     // a heap which is a percentage of your application's ideal memory foot print.  This call
  105.     // allows you to explicity define the ammount of memory used by the graphics system for
  106.     // its graphics objects heap.
  107.  
  108.     client = GXNewGraphicsClient(nil, gGraphicsHeapSize * 1024, 0L);
  109.  
  110.     if ( client )
  111.     {
  112.         // If gDebugging = TRUE, you will receive graphics library errors & notices will be posted.
  113.         // This functionality will only work with the "debugging" version of QuickDraw GX.  If you
  114.         // don't have the debugging version installed, these functions will not work. 
  115.     
  116.         if (gDebugging)
  117.         {
  118.             SetGraphicsLibraryErrors ();
  119.             SetGraphicsLibraryNotices();    
  120.         }
  121.     
  122.         // Set gGiveMeValidation to TRUE if you want run-time validation. As you increase the amount
  123.         // of validation, The drawing speed will SLOW down due to all of the internal checking. 
  124.             
  125.         // gxPublicValidation will check parameters to public routines. For additional details
  126.         // regarding the various levels of validation, see "Inside Macintosh: QuickDraw GX
  127.         // Environment and Utilties."
  128.     
  129.         if (gGiveMeValidation)
  130.             GXSetValidation(gxPublicValidation); 
  131.     
  132.     
  133.         // Initialize the new graphics and printing environments.
  134.     
  135.         if ( GXGetGraphicsError( nil ) != out_of_memory ) 
  136.         {
  137.             GXEnterGraphics();
  138.             err = GXInitPrinting();
  139.         
  140.             // Initialize the other managers, if no errors occurred.
  141.             
  142.             if ( err == noErr )
  143.             {
  144.                 gQuitting = false;
  145.                 AddResMenu(GetMHandle(mApple), 'DRVR'); // add Apple Menu items.
  146.                 DrawMenuBar();
  147.     
  148.                 // We initialize the CommonColors Library.  This will allow us to set the color of a
  149.                 // shape by calling the SetShapeCommonColor function. We will need to call
  150.                 // DisposeCommonColors when we leave, to clean up the world.
  151.     
  152.                 InitCommonColors();
  153.         
  154.                 DoCreateNew();
  155.                 
  156.                 SetCursor(&qd.arrow);  
  157.                 
  158.                 while (!gQuitting)
  159.                     EventLoop();
  160.     
  161.                 // Leaving.  Close all the windows so we get rid of any data we or GX created.  Then,
  162.                 // dispose of the common colors and exit the GX printing and graphics environment.
  163.     
  164.                 while ( (wind = FrontWindow()) != NULL )
  165.                     DoDispose(wind);
  166.     
  167.                 DisposeCommonColors();
  168.                 GXExitPrinting();    // Close the new printing mgr. 
  169.             }
  170.             
  171.             GXExitGraphics();        // Deallocate all of the default structures
  172.             
  173.         } else   DebugStr ("\p Unfortunately, there is not enough memory for GX, please quit an app...");                
  174.     }  else   DebugStr ("\p Unfortunately, there is not enough memory for GX, please quit an app...");
  175.     
  176.     GXDisposeGraphicsClient(client);
  177.     DoTeardown();            // Dispose of any global variables we made in DoSetup.
  178. }
  179.  
  180.  
  181. /**\
  182. |**| ---------------------------------------------------------------------
  183. |**| InitToolbox()
  184. |**| ---------------------------------------------------------------------
  185. \**/
  186. void InitToolbox (void)
  187. {
  188.     // Generic heap initialization.
  189.     
  190.     MaxApplZone(); 
  191.     MoreMasters(); MoreMasters(); MoreMasters(); 
  192.     MoreMasters(); MoreMasters(); MoreMasters(); 
  193.     
  194.     // Start up the toolbox so we can notify people if there's a problem
  195.     
  196.     InitGraf(&qd.thePort);
  197.     InitFonts();
  198.     InitWindows();
  199.     InitMenus();
  200.     TEInit();
  201.     InitDialogs(nil);
  202.     InitCursor();
  203. }
  204.  
  205.  
  206. /**\
  207. |**| ---------------------------------------------------------------------
  208. |**| CheckQuickDrawGX()
  209. |**| Before making any calls, we'll see if QuickDraw GX is available.
  210. |**| If it's not, then set gQuitting=true so we can avoid doing any of 
  211. |**| the rest of this application.
  212. |**| ---------------------------------------------------------------------
  213. \**/
  214. void CheckQuickDrawGX (void)
  215. {
  216.     long                theFeature;
  217.  
  218.     // Before making any calls, we'll see if QuickDraw GX is available.  If it's not,
  219.     // we'll avoid doing any of the rest of this application
  220.     
  221.     if ( (Gestalt(gestaltGraphicsVersion, &theFeature) != noErr) ||
  222.           (Gestalt(gestaltGXPrintingMgrVersion, &theFeature) != noErr))
  223.         gQuitting = true;   // QuickDraw GX is not available
  224.     
  225. #ifdef powerc
  226.     // This is a sanity check to see if the PowerPC QuickDrawGXLib is installed.
  227.     // Since we are "weak" linked to QuickDrawGXLib, the Process Manager will
  228.     // launch us even if QuickDrawGXLib is missing.  If it's missing, the
  229.     // Code Fragment Manager will leave the address of the functions we call
  230.     // unresolved, and we would crash if we tried to call that function.  So,
  231.     // we do a check here and should be prepared to exit gracefully if the 
  232.     // library is missing.  This could happen if the user has installed a
  233.     // 68K only version of QuickDraw GX.  It could also happen if the user has
  234.     // taken the QuickDraw GX extension out of the Extensions Folder.  
  235.     //
  236.     // Note - We could check this against any function we call in the library.
  237.     // GXNewGraphicsClient is the first function we call, so it's convenient.
  238.  
  239.     if ( (Ptr)GXNewGraphicsClient == kUnresolvedSymbolAddress ) 
  240.         gQuitting = true;   // QuickDraw GX is not available in Power Mac
  241. #endif
  242. }
  243.  
  244.  
  245. /**\
  246. |**| ---------------------------------------------------------------------
  247. |**| MyPrintingEventOverride()
  248. |**| Override for GXPrintingEvent.  It allows us to update our windows
  249. |**| when the moveable modal printing dialogs are moved.  Keep this in your
  250. |**| main segment, which will always be loaded when GX tries to call the routine.
  251. |**| ---------------------------------------------------------------------
  252. \**/
  253. OSErr MyPrintingEventOverride (EventRecord *event, Boolean filterEvent)
  254. {
  255.     // Handle events in whatever way is appropriate.
  256.     // MyDoEvent is our generic event handler.
  257.  
  258.     if ( !filterEvent )
  259.         MyDoEvent(event);
  260.     return noErr;
  261. }
  262.  
  263.  
  264. /**\
  265. |**| ---------------------------------------------------------------------
  266. |**| EventLoop()
  267. |**| ---------------------------------------------------------------------
  268. \**/
  269. void EventLoop ()
  270. {
  271.     EventRecord event;
  272.  
  273.     if ( WaitNextEvent(everyEvent, &event, gSleep, nil) )
  274.         MyDoEvent(&event);
  275.     else
  276.         DoIdle(FrontWindow());
  277. }
  278.  
  279.  
  280.  
  281. /**\
  282. |**| ---------------------------------------------------------------------
  283. |**| IsAppWindow()
  284. |**| This routine looks to make sure a window pointer is not nil and that
  285. |**| the window it points to is of kind userKind.  If it is, it returns
  286. |**| true, else it returns false.
  287. |**| ---------------------------------------------------------------------
  288. \**/
  289. Boolean IsAppWindow (WindowPtr wind)
  290. {
  291.     return    ((((WindowPeek) wind)->windowKind == userKind) && (wind != nil));
  292. }
  293.  
  294.  
  295. /**\
  296. |**| ---------------------------------------------------------------------
  297. |**| MyDoEvent()
  298. |**| ---------------------------------------------------------------------
  299. \**/
  300. void MyDoEvent (EventRecord *event)
  301. {
  302.     char            key;
  303.     WindowPtr         window;        // temporarily used to hold 
  304.     GrafPtr            oldPort;
  305.     unsigned long    mssg;
  306.  
  307.     mssg = event->message;
  308.     switch(event->what)
  309.     {                    
  310.         case mouseDown:
  311.             DoMouseDown(event);
  312.             break;
  313.  
  314.         case keyDown:
  315.         case autoKey:
  316.             key = mssg & charCodeMask;
  317.             if (event->modifiers & btnState)        // if button is up
  318.             {
  319.                 if (event->modifiers & cmdKey)        // if Command key
  320.                 {
  321.                     if ( event->what == keyDown )
  322.                         DoMenuCommand(MenuKey(key));
  323.                 }
  324.                 else
  325.                     LayoutEditKey( GetDocLEHandle(FrontWindow()), key);
  326.             }
  327.             break;
  328.  
  329.         case updateEvt:
  330.             window = (WindowPtr)mssg;
  331.             if ( IsAppWindow(window) )
  332.             {
  333.                 GetPort(&oldPort);
  334.                 SetPort(window);
  335.                 BeginUpdate(window);
  336.                 DoDraw(window, true);
  337.                 EndUpdate(window);
  338.                 SetPort(oldPort);
  339.             }
  340.             break;
  341.         
  342.         case activateEvt:
  343.             break;
  344.         
  345.         case osEvt:
  346.             if ( (mssg>>24)                        // if high byte of message indicates
  347.                     == suspendResumeMessage )    // this is suspend/resume event
  348.             {
  349.                 if (mssg & resumeFlag)            // if resume event
  350.                 {                                // we're switching back from another app so..
  351.                     gSleep = 0;                    // speed up  
  352.  
  353.                     // On a resume event, we need to call GXUpdateJob on all of our
  354.                     // documents' jobs.  This is important because the user may have
  355.                     // just changed something which affects our jobs (like the size
  356.                     // of the paper in the printer).
  357.                     //
  358.                     // Since our application stores our document references in the refCon fields
  359.                     // of our documents' windows, we just loop through every one of our windows,
  360.                     // extract our document pointers and update the associated jobs.
  361.         
  362.                     LayoutEditActivate( GetDocLEHandle(FrontWindow()) );
  363.                     LayoutEditFromScrap( GetDocLEHandle(FrontWindow()) );
  364.                     window = FrontWindow();
  365.                     while (window != nil)
  366.                     {
  367.                         if ( IsAppWindow(window) )
  368.                             GXUpdateJob(GetDocJob(window));
  369.                         window = (WindowPtr) ((WindowPeek) window)->nextWindow;
  370.                     }
  371.                 }
  372.                 else                            // if suspend event
  373.                 {
  374.                     gSleep=80;                    // we're switching to another app so slow down...
  375.                     LayoutEditToScrap( GetDocLEHandle(FrontWindow()) );
  376.                     LayoutEditDeactivate( GetDocLEHandle(FrontWindow()) );
  377.                 }
  378.             }
  379.             break;
  380.     }
  381. }
  382.  
  383.  
  384. /**\
  385. |**| ---------------------------------------------------------------------
  386. |**| DoMouseDown
  387. |**| handle DoMouseDown events
  388. |**| ---------------------------------------------------------------------
  389. \**/
  390. void DoMouseDown (EventRecord *event)
  391. {
  392.     WindowPtr   window;
  393.     short       clickArea;
  394.     Rect        screenRect;
  395.  
  396.     clickArea = FindWindow( event->where, &window );
  397.     switch (clickArea)
  398.     {
  399.         case inSysWindow:
  400.             SystemClick(event, window);
  401.             break;
  402.                         
  403.         case inDrag:
  404.             screenRect = (**GetGrayRgn()).rgnBBox;
  405.             if ( IsAppWindow(window) )
  406.                 DragWindow( window, event->where, &screenRect );
  407.             break;
  408.  
  409.         case inContent:
  410.             if (IsAppWindow(window))
  411.             {
  412.                 if ( window == FrontWindow())
  413.                     DoClick(window, event->where);
  414.                 else
  415.                      SelectWindow(window);
  416.             }
  417.             break;
  418.         
  419.         case inGoAway:
  420.             if ( IsAppWindow(window) )
  421.             {
  422.                 if ( TrackGoAway(window, event->where) )
  423.                     DoDispose(window);
  424.             }
  425.             break;
  426.         
  427.         case inMenuBar:
  428.             DoMenuCommand(MenuSelect(event->where));
  429.             break;
  430.  
  431.     }
  432. }
  433.